#include <iostream>
using namespace std;
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

void handler(int sig){
    //回收任意一个子进程
    while(1){
        int rd = waitpid(-1, nullptr, WNOHANG);
        if(rd < 0){
            cout << "回收失败" << endl;
            break;
        }
        else if(rd == 0){
            cout << "本轮回收结束" << endl;
            break;
        }
        else{
            cout << "回收成功" << endl;
        }
    }
}

int main(){
    //signal(SIGCHLD, handler);

    // 设置SIGCHLD信号的处理动作为SIG_IGN
    signal(SIGCHLD, SIG_IGN);

    for(int i = 0; i < 10; ++i){
        //一次性创建10个子进程
        pid_t id = fork();
        if(id < 0){
            cerr << "fork error" << endl;
            return id;
        }
        else if(id == 0){
            // 子进程
            sleep(3);
            cout << "process" << getpid() << " over!" << endl;
            exit(1);
        }
    }

    //父进程
    while(1){
        cout << "i am father, pid is " << getpid() << endl;
        sleep(1);
    }

    return 0;
}
















// 测试 volatile

/* volatile int flag = 0;

void handler(int sig){
    cout << "进程" << getpid() << " 接收到信号" << sig << endl;
    flag = 1;
}



int main(){
    signal(2, handler);
    while(!flag){}
    cout << "正常退出进程" << endl;
    return 0;
} */







// 测试sigaction

/* void PrintPending(sigset_t& pending){
    for(int i = 31; i >= 1; --i){
        int ret = sigismember(&pending, i);
        cout << ret;
    }
    cout << endl;
}

void handler(int sig){
    cout << "进程" << getpid() << " 接收到信号" << sig << endl;
    sigset_t pending;
    sigpending(&pending);
    PrintPending(pending);

    //不让这个函数退出
    while(1){
        // 在这里的时候，再次发送信号，看一下pending表
        // 如果pending表中位置变成 0 -> 1， 那么就说明被阻塞了
        sigpending(&pending);
        PrintPending(pending);
        sleep(1);
    }
    
}


int main(){
    struct sigaction act, oact;
    act.sa_handler = handler;
    act.sa_flags = 0; // 这个可能会影响结果，所以初始化一下

    //将3 ~ 9号屏蔽
    sigset_t mask;
    for(int i = 3; i < 10; ++i){
        sigaddset(&mask, i);
    }
    act.sa_mask = mask;

    sigaction(SIGINT, &act, &oact);

    while(1){
        cout << "my pid is " << getpid() << endl;
        sleep(1);
    }

    return 0;
} */